package com.ezops.dao.facade;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ezops.dao.ClientTradeDAO;
import com.ezops.dao.generics.dao.hibernate.GenericDAO;
import com.ezops.dto.FileData;
import com.ezops.models.ClientTradeFile;
import com.ezops.util.TradeStatus;

@Service
public class FileMonitorFacade extends DataTransferFacadeImpl<ClientTradeFile>
		implements IFileMonitorFacade {

	@Autowired
	private ClientTradeDAO dao;

	@Autowired
	private ITradeClientDataTransferFacade clientFacade;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ezops.dao.facade.IFileMonitorFacade#getAllFileData()
	 */
	@Override
	public List<FileData> getAllFileData() {
		// TODO - Instead of getting all rows in grouping it progrmatically, its
		// better to use database group by clause and use {@code
		// ResultTransformer} to transfer it into the required dto.
		List<ClientTradeFile> tradeFiles = dao.findAll();
		List<FileData> fileData = convertTo(tradeFiles);
		return fileData;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ezops.dao.facade.IFileMonitorFacade#getClientForBatch(int)
	 */
	@Override
	public int getClientForBatch(int batchId) {
		return dao.getClientForBatch(batchId);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ezops.dao.facade.IFileMonitorFacade#getTradeStatus()
	 */
	@Override
	public Map<String, String> getTradeStatus() {

		int failedFileCount = dao.getFailedFileCount();
		int failedTradeCount = dao.getFailedTradeCount();
		Map<String, String> statusMap = new HashMap<>();

		statusMap.put("failFailCount", String.valueOf(failedFileCount));
		statusMap.put("failTradeCount", String.valueOf(failedTradeCount));

		return statusMap;
	}

	private List<FileData> convertTo(List<ClientTradeFile> tradeFiles) {
		SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss");

		Map<Integer, FileData> aggregatedResult = new HashMap<Integer, FileData>();

		for (ClientTradeFile tradeFile : tradeFiles) {
			if (aggregatedResult.containsKey(tradeFile.getId())) {
				FileData data = aggregatedResult.get(tradeFile.getId());
				switch (TradeStatus.valueOf(tradeFile.getStatus())) {
				case FAILED:
					data.setPending(data.getPending() + 1);
					data.setStatus("Failed");
					break;

				case PENDING:
				case PROCESSED:
					data.setProcessed(data.getProcessed() + 1);
				}
				data.setTotal(data.getTotal() + 1);

			} else {
				FileData fileData = new FileData();
				fileData.setBatchId(String.valueOf(tradeFile.getId()));

				fileData.setClient(clientFacade.reverseLookUp(tradeFile
						.getClientId()));
				fileData.setDatetime(sdf.format(tradeFile.getProcessedDate()));
				fileData.setManager("Macro Fund");
				fileData.setType("CLIENT TRADES");
				fileData.setSource("OT");

				switch (TradeStatus.valueOf(tradeFile.getStatus())) {
				case FAILED:
					fileData.setPending(1);
					fileData.setStatus("Failed");
					break;

				case PENDING:
				case PROCESSED:
					fileData.setProcessed(1);
				}

				fileData.setTotal(fileData.getTotal() + 1);

				// /TODO :Remove parseInt
				aggregatedResult.put(Integer.parseInt(tradeFile.getId()),
						fileData);
			}
		}
		return new ArrayList<>(aggregatedResult.values());
	}

	@Override
	public GenericDAO<ClientTradeFile, Serializable> getDataAccessObject() {
		// TODO Auto-generated method stub
		return dao;
	}

}
